using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using Rotempco.Core.Logic;

namespace Rotempco.Core.ORM.Logic
{
    public class SymmetricEncryptionLogic
    {
        public static string Encrypt(object input)
        {
            return Encrypt(input, CoreSettingsLogic.GetSymmetricEncryptionKey());
        }

        public static string Encrypt(object input, string key)
        {
            return Encrypt(SerializerLogic.SerializeObject(input), key);
        }

        public static string Encrypt(string input)
        {
            return Encrypt(input, CoreSettingsLogic.GetSymmetricEncryptionKey());
        }

        public static string Encrypt(string input, string key)
        {
            if (string.IsNullOrEmpty(key))
                throw new Exception("Missing Encryption key");

            byte[] keyArray;
            byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(input);

            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
            hashmd5.Clear();

            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            tdes.Key = keyArray;
            tdes.Mode = CipherMode.ECB;
            tdes.Padding = PaddingMode.PKCS7;

            ICryptoTransform cTransform = tdes.CreateEncryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
            tdes.Clear();
            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }

        public static object DecryptObject(string input)
        {
            return Decrypt(input, CoreSettingsLogic.GetSymmetricEncryptionKey());
        }

        public static object DecryptObject(string input, string key)
        {
            string value = Decrypt(input, key);
            return SerializerLogic.Deserialize(value);
        }

        public static string Decrypt(string input)
        {
            return Decrypt(input, CoreSettingsLogic.GetSymmetricEncryptionKey());
        }

        public static string Decrypt(string input, string key)
        {
            if (string.IsNullOrEmpty(key))
                throw new Exception("Missing Encryption key");

            if (string.IsNullOrEmpty(input))
                return null;

            byte[] keyArray;
            byte[] toEncryptArray = Convert.FromBase64String(input);

            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
            hashmd5.Clear();

            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            tdes.Key = keyArray;
            tdes.Mode = CipherMode.ECB;
            tdes.Padding = PaddingMode.PKCS7;

            ICryptoTransform cTransform = tdes.CreateDecryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
            tdes.Clear();
            return UTF8Encoding.UTF8.GetString(resultArray);
        }

        public static byte[] EncryptFile(byte[] byteArray)
        {
            return EncryptFile(byteArray, CoreSettingsLogic.GetSymmetricEncryptionKey());
        }

        public static void EncryptFile(string tempImagePath, string finalImagePath)
        {
            string key = CoreSettingsLogic.GetSymmetricEncryptionKey();

            if (string.IsNullOrEmpty(key))
                throw new Exception("Missing Encryption key");

            byte[] data = File.ReadAllBytes(tempImagePath);

            byte[] resultArray = EncryptFile(data, key);

            File.WriteAllBytes(finalImagePath, resultArray);
        }

        private static byte[] EncryptFile(byte[] byteArray, string key)
        {
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            byte[] keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
            hashmd5.Clear();

            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            tdes.Key = keyArray;
            tdes.Mode = CipherMode.ECB;
            tdes.Padding = PaddingMode.PKCS7;

            ICryptoTransform cTransform = tdes.CreateEncryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(byteArray, 0, byteArray.Length);
            tdes.Clear();

            return resultArray;
        }

        public static byte[] DecryptFile(string imagePath)
        {
            string key = CoreSettingsLogic.GetSymmetricEncryptionKey();

            if (string.IsNullOrEmpty(key))
                throw new Exception("Missing Encryption key");

            byte[] toEncryptArray = File.ReadAllBytes(imagePath);

            return DecryptFile(toEncryptArray,key);
        }

        public static byte[] DecryptFile(byte[] byteArray)
        {
            return DecryptFile(byteArray,CoreSettingsLogic.GetSymmetricEncryptionKey());
        }

        private static byte[] DecryptFile(byte[] byteArray, string key)
        {
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            byte[] keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
            hashmd5.Clear();

            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            tdes.Key = keyArray;    
            tdes.Mode = CipherMode.ECB;
            tdes.Padding = PaddingMode.PKCS7;

            ICryptoTransform cTransform = tdes.CreateDecryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(byteArray, 0, byteArray.Length);
            tdes.Clear();

            return resultArray;
        }                
    }
}
